#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Time: 2019/7/30  9:55
# @Author: 余浪人
# @email: yulangren520@gmail.com
import re, json, math
from functools import wraps
from flask import request, jsonify
from apps.lib.cache_sys import sys_cache
from apps.lib.public import redis_, private_untie
from apps.setting import Config
from apps.models.synthesize_model import TL_WebApp_Model


def notNull(string: str):
    if string:
        return string
    return ''


def apiErrors(obj):
    '''
    验证数据合法性
    :param obj: 查询对象
    :return:
    '''
    if obj is None:
        return jsonify({"status": 400, "msg": "数据有误,验证失败!"})


def page_auto(obj_list, page_interval: int, astrict: int = 0):
    '''
    系统分页
    :param obj_list:
    :return: data_list(数据列表),page(分页对象)
    '''
    try:
        if request.method == 'POST':
            page = int(request.form.get('page', 1))
        else:
            page = int(request.args.get('page', 1))
        if page <= 0: page = 1
    except:
        page = 1
    if astrict != 0 and page > astrict: page = astrict  # 页数限制
    if obj_list.count() < page_interval:
        page_interval = obj_list.count()  # 数据不足 取最大条数
    try:
        res = math.ceil(obj_list.count() / page_interval)
    except:
        res = 1
    if res < page: page = 1  # 当页码超出时   返回第一页
    paginate = obj_list.paginate(page, page_interval)
    # 判断是否为空
    return paginate.items, paginate


def img(imgUrl, string: str):
    '''返回一个url'''
    if imgUrl:
        return imgUrl
    img = ''.join(re.findall('<img.*src="(.*?\..*?)"', string.lower(), flags=re.S)[:1])
    return img


def content(contentList: list, strftime=None):
    '''
    处理列表页面的内容内容返回值
    :param contentList:
    :return:
    '''
    data = [
        {
            "title": content.title,
            'ID': content.uuid,
            'update_time': content.update_time.strftime(strftime) if strftime else content.update_time,
            'title_color': content.title_color,
            'imgUrl': img(content.thumb_img, content.content),
            'PID': content.pro.column_name,
            'PID_ID': content.pro.uuid,
            'author': content.author,
            'clicks': content.clicks,
            'contributor': content.contributor,
            'description': content.description,
            'column_link': content.pro.column_link,
            'comment_num': len(content.comment_model),
            'original':content
        }
        for content in contentList if content.status == 1
    ]
    return data


# ************ 点击数 ***********************
def click_up(obj):
    def inner(*args, **kwargs):
        new_obj = obj(*args, **kwargs)
        try:
            from apps.models.content_model import Content_Model, db
            pid = request.json.get('pid') if request.is_json else request.form.get('pid')
            con = Content_Model.query.filter_by(uuid=pid, status=1).first()
            con.set_attrs({'clicks': con['clicks'] + 1})
            db.session.commit()
        except:
            pass
        return new_obj

    return inner


# 接口权限验证
def authority(obj):
    @wraps(obj)
    def inner(*args, **kwargs):
        try:
            sys = sys_cache()
            if not sys.web_on_off: return jsonify({"status": 1, "msg": "站点未开启,请求失败!", "tipsMsg": sys.web_close_tips})
            csrf_token = request.headers.get('csrf-token')
            if not csrf_token: return jsonify({"status": 1, "msg": "身份验证失败,请添加身份!"})
            webApi = TL_WebApp_Model.query.first()
            if webApi.status == 0: return jsonify({"status": 1, "msg": "数据接口未开启!"})
            if webApi.private_code != private_untie(webApi.private_pem, csrf_token): return jsonify({"status": 1, "msg": "身份授权验证失败,授权码错误!"})
            new = obj(*args, **kwargs)
        except:
            return jsonify({"status": 1, "msg": "接口权限验证异常,请联系网站管理员!"})
        return new

    return inner


# 评论权限验证
def conmmentAuthority(obj):
    @wraps(obj)
    def inner(*args, **kwargs):
        sys = sys_cache()
        if not sys.web_content_on_off: return jsonify({"status": 1, "msg": "评论功能未开启,评论失败!"})
        new = obj(*args, **kwargs)
        return new

    return inner


# 添加访问者ip
def ipAdd(obj):
    @wraps(obj)
    def inner(*args, **kwargs):
        IP = request.remote_addr
        redis_2 = redis_(2)
        val = redis_2.get(IP)
        if not val:
            data = {"IP": IP, "count": 1}
            redis_2.set(IP, json.dumps(data), 60)
        else:
            if redis_2.ttl(IP) > 2:
                old = json.loads(val)
                data = {"IP": IP, "count": old['count'] + 1}
                redis_2.set(IP, json.dumps(data), redis_2.ttl(IP) - 1)
        redis_2.close()
        new = obj(*args, **kwargs)
        return new

    return inner


# 验证访问者ip json
def ipAuthority(obj):
    @wraps(obj)
    def inner(*args, **kwargs):
        IP = request.remote_addr
        redis_2 = redis_(2)
        redis_3 = redis_(3)
        val = redis_2.get(IP)
        if val:
            old = json.loads(val)
            if old['count'] == Config.MAX_NUM:
                redis_3.set(IP, json.dumps(IP), Config.RESTRICT_TIME * 60)  # 冻结IP
                redis_2.delete(IP)
                redis_2.close()
                redis_3.close()
                return jsonify({"status": 1, "msg": "访问过快,超过网站限制频率!稍稍休息,可继续访问哟"})
        redis_2.close()
        if redis_3.get(IP):
            redis_3.close()
            return jsonify({"status": 1, "msg": "访问过快,超过网站限制频率,限制访问!稍稍休息,可继续访问哟"})
        redis_4 = redis_(4)  # 永久
        if redis_4.hget('forbid_ip',IP):
            redis_4.close()
            return jsonify({"status": 1, "msg": "访问拒绝,限制访问!"})
        new = obj(*args, **kwargs)
        return new

    return inner


def nav_list(navList: list, pid: int = 0):
    data = [
        {
            'column_name': col.column_name,
            'column_link': col.column_link,
            'column_ID': col.uuid,
            'column_uuid': col.uuid,
            'column_keyword': col.column_keyword,
            'column_description': col.column_description,
            'content_model':col.content_model,
            'dataList': nav_list(navList, pid=col['id']),
        }
        for col in navList if col['column_parent_id'] == pid
    ]
    return data
